package org.xx.armory.commons;

import java.util.Arrays;

import static java.lang.System.arraycopy;
import static org.xx.armory.commons.Validators.rejectIf;
import static org.xx.armory.commons.Validators.rejectIfNegative;

/**
 * 不可变的字符数组，用于表示口令等不希望被缓存的数据。
 */
public final class CharArray
        implements CharSequence {
    private final char[] chars;

    public CharArray(
            char... chars
    ) {
        this(chars, 0, chars != null ? chars.length : 0);
    }

    public CharArray(
            char[] chars,
            int start,
            int end
    ) {
        rejectIfNegative(start, "start");
        rejectIfNegative(end, "end");
        rejectIf(() -> end < start, "Argument \"start\" must less or equals to \"end\"");

        if (chars == null) {
            this.chars = new char[0];
        } else {
            this.chars = new char[end - start];
            arraycopy(chars, start, this.chars, 0, end - start);
        }
    }

    @Override
    public int length() {
        return this.chars.length;
    }

    @Override
    public char charAt(
            int index
    ) {
        return this.chars[index];
    }

    @Override
    public CharSequence subSequence(
            int start,
            int end
    ) {
        return new CharArray(this.chars, start, end);
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(this.chars);
    }

    @Override
    public boolean equals(
            Object obj
    ) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof final CharArray other)) {
            return false;
        }
        return Arrays.equals(this.chars, other.chars);
    }

    @Override
    public String toString() {
        return this.chars.length == 0 ? "" : new String(this.chars);
    }
}
